from PyQt6.QtWidgets import QLabel
from PyQt6.QtGui import QImage,QPixmap,QTransform
from PyQt6.QtCore import Qt
import pdf2image
import time
import os
import base64
from utils.Logger import LogPrint
from utils import PdfUtils
from utils.PdfConvertTask import PdfConvertTask

class PdfPreView(QLabel):
    def __init__(self, parent=None):
        super().__init__()
        #self.label = QLabel("标签显示文字", parent)
        #self.label.move(20,20) # 控件的偏移量

        self.setText("标签显示文字")
        self.pdfShowWidth=300
        self.pdfShowMaxHeight=300

        #是否从文件加载image
        self.loadFromLocalFile=True
        self.tempFileDir=None

        #错误信息回调
        self.errorInfoCallback=None

        #加载完成回调
        self.onLoadFinishCallback=None

        #选择的页码列表
        self.pageNoList=[]
        #当前显示的pageIndex，从0开始
        self.currentPageNoIndex=0
        
    #返回pdf页码总数
    def loadPdf(self, pdfFilePath, pageNoList=None,errorInfoCallback=None):
        self.errorInfoCallback=errorInfoCallback

        LogPrint.debug(pdfFilePath,pageNoList)
        
        # 使用pdf转成image
        if pdfFilePath is None or pdfFilePath=='':
            self.dealErrorInfo('未选择pdf文件')
            self.setText('未选择pdf文件')
            return -1
        
        self.pageNoList.clear()
        if pageNoList:
            for pageNo in pageNoList:
                self.pageNoList.append(pageNo)

        self.pdfTask=PdfConvertTask(parent=self)
        LogPrint.info('begin startPdfConvertTask')
        self.pdfTask.startPdfConvertTask(pdfFilePath,callback=self.afterPdfConvert)
       

        return len(self.pageNoList)
    
    #线程转换图片后续逻辑
    def afterPdfConvert(self,images,tempFileDir):

        LogPrint.info(tempFileDir)

        #self.pdfTask.unInit()

        if tempFileDir is not None and len(tempFileDir)>0:
            self.images =  images
            self.tempFileDir=tempFileDir
        else :
            self.dealErrorInfo('pdf不存在或者打开错误')
            self.setText('pdf不存在或者打开错误')
            return     
        
        if len(self.pageNoList)==0:
            pdfPageCount=self.getPageCount()
            if pdfPageCount<1:
                self.dealErrorInfo('pdf页码加载错误，总页数是0')
                return -1
            for pageNo in range(1,pdfPageCount+1):
                self.pageNoList.append(pageNo)

        #当前显示页面索引
        self.currentPageNoIndex=0

        pdfShowHeight=self.showSpecifiedPage(self.pageNoList[0])

        if self.onLoadFinishCallback:
            self.onLoadFinishCallback(len(self.pageNoList),pdfShowHeight)

    def setOnLoadFinishCallback(self,onLoadFinishCallback):
        self.onLoadFinishCallback=onLoadFinishCallback
    
    def getPageCount(self):
        if self.loadFromLocalFile:
            if self.tempFileDir and os.path.exists(self.tempFileDir):
                    fileList = PdfUtils.getPdfImageList(self.tempFileDir)
                    if fileList and len(fileList) > 0:
                        return len(fileList)
        else :
            if self.images:
                return len(self.images)
        return 0


    
    def isTurnLeft(self):
        if self.currentPageNoIndex <= 0:
            return False
        else :
            return True
        
    def isTurnRight(self):
        if self.currentPageNoIndex >= len(self.pageNoList)-1:
            return False
        else :
            return True
        
    #向左翻页
    def turnLeftPage(self):
        LogPrint.debug('turnLeftPage',self.pageNoList,self.currentPageNoIndex)
        if self.currentPageNoIndex > 0:
            self.currentPageNoIndex-=1
            pageNo=self.pageNoList[self.currentPageNoIndex]
            self.showSpecifiedPage(pageNo)

            return self.currentPageNoIndex+1
        else:
            return 1

    #向右翻页
    def turnRightPage(self):
        LogPrint.debug('turnRightPage',self.pageNoList,self.currentPageNoIndex)
        if self.currentPageNoIndex < len(self.pageNoList):
            self.currentPageNoIndex+=1
            self.showSpecifiedPage(self.pageNoList[self.currentPageNoIndex])

            return self.currentPageNoIndex+1
        else:
            return len(self.pageNoList)

    #打开指定页码,pageIndex从1开始，返回图片高度
    def showSpecifiedPage(self,pageIndex):
        currMillis = int(round(time.time() * 1000))
        pdfShowHeight=self.pdfShowWidth
        if pageIndex>0 and pageIndex in self.pageNoList:
            #如果从本地文件加载
            if self.loadFromLocalFile:
                if self.tempFileDir and os.path.exists(self.tempFileDir):
                    fileList = PdfUtils.getPdfImageList(self.tempFileDir)
                    if fileList and len(fileList) > 1:
                        # for fileName in fileList:
                        #     LogPrint.info('showSpecifiedPage fileName:',fileName)
                        pageIndex-=1
                        filePath=self.tempFileDir+'/'+fileList[pageIndex]
                        LogPrint.debug(filePath,pageIndex)
                        qImage = QImage(filePath)

            else:
                if self.images:
                    pageIndex-=1
                    showImage=self.images[pageIndex]
                    #LogPrint.info(f'showSpecifiedPage showImage width:{showImage.width},height: {showImage.height}')
                    reduceProp=showImage.width/self.pdfShowWidth
                    #把图片按比例缩小
                    qImageWidth=self.pdfShowWidth
                    qImageHeight=int(showImage.height/reduceProp)
                    #LogPrint.info(f'after reduce,image width:{qImageWidth},height:{qImageHeight}')
                    qImage = QImage(showImage.tobytes("raw", "RGB"), showImage.width, showImage.height,
                                    QImage.Format.Format_BGR888)
            if qImage:
                    width = qImage.width()
                    height = qImage.height()
                    LogPrint.debug(f'after reduce,qImage width:{width},height:{height}')
                    #QImage 转为QPixmap
                    pix = QPixmap.fromImage(qImage)
                    trans = QTransform()
                    trans.rotate(0)  # 这里设置旋转角度
                    new = pix.transformed(trans)
                    # 设置标签宽和高
                    pdfShowHeight=int(height*self.pdfShowWidth/width)
                    #LogPrint.info(f'setFixedSize,pdfview width:{self.pdfShowWidth},height:{pdfShowHeight}')
                    self.setFixedSize(self.pdfShowWidth, pdfShowHeight) #存放pdf 控件大小
                    # 设置图片大小自适应标签
                    self.setScaledContents(True)
                    #给标签设置图像
                    self.setPixmap(new)
                    cost=int(round(time.time() * 1000))-currMillis
                    #LogPrint.info('showSpecifiedPage cost',cost)
            else:
                LogPrint.info('showSpecifiedPage qImage object is none')

        return pdfShowHeight


    def dealErrorInfo(self,content):
        #LogPrint.info('dealErrorInfo',content)
        LogPrint.error(content)
        if self.errorInfoCallback:
            self.errorInfoCallback(content)

    def pdfToImage(self,pdfPath):
        images=None
        try :
            if self.loadFromLocalFile:
                # 使用os.path.split()分割路径和文件名
                dirname, filename = os.path.split(pdfPath)
                #LogPrint.info(dirname,filename)
                strFiles=str(filename).split('.')
                if strFiles and len(strFiles)>1:
                    strName=strFiles[0]
                else :
                    strName = base64.b64encode(pdfPath.encode('utf-8'))
                outputPath=dirname+'/tmp/'+strName
                # 检查目录是否存在
                if not os.path.exists(outputPath):
                    # 如果目录不存在，则创建目录
                    os.makedirs(outputPath)
                images = pdf2image.convert_from_path(pdfPath,dpi=50,first_page=1,thread_count=5,output_folder=outputPath,
                                                    fmt='jpeg',output_file='tmp')
                self.tempFileDir=outputPath
            else:
                images = pdf2image.convert_from_path(pdfPath,dpi=50,first_page=1,thread_count=5)
        except Exception as e:
            LogPrint.info('pdfToImage 读取pdf文件失败',e)
        return images
    
